package com.example.boot.aop;

import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.example.utils.SpringContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.Stack;

/**
 * TODO
 *
 * @author ding
 * @since 2024/7/9
 */
//@Aspect
//@Component
//@Slf4j
//public class TransactionAspect {
//    //切入点  返回值 包.类.方法(参数)  ..表示参数
//    //指定加了注解的才拦截
//    @Pointcut("execution(* com.example.service.Impl.*.*(..)) && @annotation(com.example.common.MoreTransaction)")
//    public void moreTransaction() {
//    }
//
//    @Around("moreTransaction()&&@annotation(annotation)")
//    public Object twoTransaction(ProceedingJoinPoint thisJoinPoint, MoreTransaction annotation) throws Throwable {
//        //存放事务管理器的栈
//        Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack = new Stack<>();
//        //存放事务状态
//        Stack<TransactionStatus> transactionStatusStack = new Stack<>();
//        try{
//            // 检查是否有需要开启事务的事务管理器名字
//            if(!openTransaction(dataSourceTransactionManagerStack,transactionStatusStack,annotation))
//                return null;
//            Object proceed= thisJoinPoint.proceed();
//            //如果没有异常，说明两个sql都执行成功，两个数据源的sql全部提交事务
//            commit(dataSourceTransactionManagerStack, transactionStatusStack);
//            return proceed;
//        }catch (Throwable e){
//            //业务代码发生异常，回滚两个数据源的事务
//            rollback(dataSourceTransactionManagerStack, transactionStatusStack);
//            log.error(String.format("MultiTransactionalAspect, method:%s-%s occors error:",
//                    thisJoinPoint.getTarget().getClass().getSimpleName(), thisJoinPoint.getSignature().getName()), e);
//            throw e;
//        }
//    }
//
//    private boolean openTransaction(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack, Stack<TransactionStatus> transactionStatusStack, MoreTransaction annotation) {
//        // 获取需要开启事务的事务管理器名字
//        String[] transactionMangerNames = annotation.value();
//        // 检查是否有需要开启事务的事务管理器名字
//        if (ArrayUtils.isEmpty(annotation.value())) {
//            return false;
//        }
//        // 遍历事务管理器名字数组，逐个开启事务并将事务状态和管理器存入栈中
//        for (String beanName : transactionMangerNames) {
//            // 从Spring上下文中获取事务管理器
//            DataSourceTransactionManager dataSourceTransactionManager =(DataSourceTransactionManager) SpringContextUtil.getBean(beanName);
//            // 创建新的事务状态
//            TransactionStatus transactionStatus = dataSourceTransactionManager
//                    .getTransaction(new DefaultTransactionDefinition());
//            // 将事务状态和事务管理器存入对应的栈中
//            transactionStatusStack.push(transactionStatus);
//            dataSourceTransactionManagerStack.push(dataSourceTransactionManager);
//        }
//        return true;
//    }
//
//    private void commit(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
//                        Stack<TransactionStatus> transactionStatuStack) {
//        // 循环，直到事务管理器栈为空
//        while (!dataSourceTransactionManagerStack.isEmpty()) {
//            // 从事务管理器栈和事务状态栈中分别弹出当前的事务管理器和事务状态
//            // 提交当前事务状态
//            dataSourceTransactionManagerStack.pop()
//                    .commit(transactionStatuStack.pop());
//        }
//    }
//
//    private void rollback(Stack<DataSourceTransactionManager> dataSourceTransactionManagerStack,
//                          Stack<TransactionStatus> transactionStatuStack) {
//        // 循环，直到事务管理器栈为空
//        while (!dataSourceTransactionManagerStack.isEmpty()) {
//            // 从事务管理器栈和事务状态栈中分别弹出当前的事务管理器和事务状态
//            // 回滚当前事务状态
//            dataSourceTransactionManagerStack.pop().rollback(transactionStatuStack.pop());
//        }
//    }
//
//}
